<template>
	<view class="custom_upload mtb20">
		<!-- #ifdef MP-WEIXIN -->
		<root-portal>
		<!-- #endif -->
			<u-popup :show="showPopup" @close="close" closeOnClickOverlay round="20rpx" :safeAreaInsetBottom="true" closeable
				z-index="75">
				<view class="upload_content p25 column">
					<text class="bold center mb20" style="color: #000">{{ title }}</text>
					<view class="mt20">
						<u-button shape="circle" text="拍照" @click="uploadImg('Camera')" color="#F5F5F5"
							:custom-style="{ marginRight: '10rpx', height: '96rpx', color: '#979797' }"></u-button>
						<u-button shape="circle" type="primary" text="相册" @click="uploadImg('Album')"
							:custom-style="{ height: '96rpx', marginTop: '24rpx' }"></u-button>
					</view>
				</view>
			</u-popup>
		<!-- #ifdef MP-WEIXIN -->
		</root-portal>
		<!-- #endif -->
		<!-- <systemAuthorization ref="openModelRef" /> -->
		<!-- 图片裁剪 -->
		<l-clipper v-if="isShowCrop" :image-url="clipperSrc" :width="tailorwidth" :height="tailorHeight"
			@success="clipperSuccess" :max-ratio="10" @cancel="isShowCrop = false" is-limit-move :is-show-photo-btn="false" />
		<view class="" @click="props.readonly ? null : openPopup()">
			<slot>
				<view class="choose_box" :style="{ 'grid-template-columns': ` repeat(${chooseBoxGrid},1fr)` }">
					<slot name="list">
						<view class="images_box" :style="imageBoxStyle" v-for="(item, index) in images"
							v-if="images[0] !== '' && images.length > 0" :key="index">
							<u-transition show mode="fade-right">
								<u-image showLoading lazyLoad @click.passive.stop="previewImage(index, images)" :src="item" width="100%"
									:height="imageBoxStyle.height ? imageBoxStyle.height : '200rpx'" radius="17rpx" />
								<view class="close_icon centerV" @click.passive.stop="onDelItem(index)">
									<u-icon name="close" color="#fff" size="22rpx" bold></u-icon>
								</view>
							</u-transition>
						</view>
					</slot>
					<view class="upload_box centerV" :style="imageBoxStyle"
						@click.passive.stop="props.readonly ? null : openPopup()" v-if="!(maxLength == 1 && images.length == 1)">
						<slot name="upload-image">
							<u-icon name="plus" size="57rpx" color="#AAAAAA" bold />
						</slot>
					</view>
				</view>
			</slot>
		</view>
	</view>
</template>

<script setup>
	import {
		ref,
		watchEffect
	} from 'vue';
	import fileUpload from '@/utils/request/upload/upload';
	// import permision from "@/js_sdk/wa-permission/permission.js"
	import {
		doUploadsReady
	} from '@/api/upload.js';
	import {
		showToast,
		previewImage
	} from '@/core/app';
	const props = defineProps({
		value: {
			type: [String],
			default: ''
		},
		show: {
			type: Boolean,
			default: false
		},
		title: {
			type: String,
			default: '上传图片'
		},
		chooseBoxGrid: {
			type: [Number, String],
			default: 3
		},
		options: {
			type: Object,
			default: () => ({})
		},
		maxLength: {
			type: Number,
			default: 1
		},
		uploadType: {
			type: String,
			default: 'list'
		},
		imageBoxStyle: {
			type: Object,
			default: () => ({})
		},
		readonly: {
			type: Boolean,
			default: false
		},
		isTailor: {
			//是否裁剪
			type: Boolean,
			default: false
		},
		tailorwidth: {
			//裁剪宽度
			type: Number,
			default: 200
		},
		tailorHeight: {
			//裁剪高度
			type: Number,
			default: 200
		}
	});
	const emits = defineEmits(['update:value', 'update:show', 'close', 'uploadSuccess']);
	// 图片列表
	const images = ref([]);
	const showPopup = ref(props.show);
	watchEffect(() => {
		images.value = props.value ? props.value.split(',') : [];
		showPopup.value = props.show;
	});
	// 打开popup
	const openPopup = () => {
		if (props.uploadType == 'list') {
			if (images.value.length >= props.maxLength) return showToast(`最多只能上传${props.maxLength}张`);
		}
		showPopup.value = true;
	};
	// 关闭popup
	const close = () => {
		showPopup.value = false;
		emits('update:show', false);
		emits('close', false);
	};
	// 上传头像
	const isShowCrop = ref(false); //是否显示裁剪
	const clipperSrc = ref(undefined); //裁剪的图片
	const uploadImg = async (type = '') => {
		if (props.maxLength > 1 && props.isTailor) {
			console.warn('上传多张照片时(maxLength>1)不允许使用裁剪(isTailor==true)');
			return;
		}
		if (props.uploadType == 'list') {
			if (images.value.length >= props.maxLength) return showToast(`最多只能上传${props.maxLength}张`);
		}
		// #ifdef APP
		if (!empowerCameraAlbum(type)) return;
		// #endif
		const fupload = new fileUpload({
			count: props.maxLength || 1
		});

		const data1 = await fupload.ossImagUpload({
			...props.options,
			sourceType: [type.toLocaleLowerCase()],
			count: props.maxLength
		});
		for (let item of data1) {
			const result = await doUploadsReady(item);
			if (result) {
				const {
					data
				} = result;
				uni.uploadFile({
					url: data.host,
					filePath: item.path,
					name: 'file',
					formData: {
						key: data.key,
						policy: data.policy,
						OSSAccessKeyId: data.ossAccessKeyId,
						signature: data.signature
					},
					success: async (res) => {
						if (res.statusCode === 204) {
							const filePath = data.host + '/' + data.key;
							if (props.uploadType == 'list') {
								if (images.value.length >= props.maxLength) return showToast(`最多只能上传${props.maxLength}张`);
							}
							if (props.uploadType == 'list') {
								images.value.push(filePath);
							} else {
								images.value = filePath;
							}
							if (!props.isTailor) {
								emits('uploadSuccess', typeof images.value == 'string' ? images.value : images.value.join(
									','));
								emits('update:value', typeof images.value == 'string' ? images.value : images.value.join(','));
							} else {
								clipperSrc.value = typeof images.value == 'string' ? images.value : images.value.join(',')[0];
								isShowCrop.value = true;
							}
							close();
						}
					},
					fail: (err) => {}
				});
			}
		}
	};
	// 裁剪成功
	const clipperSuccess = async (e) => {
		const result = await doUploadsReady({
			model: 'image',
			name: `${new Date().getDate()}.png`,
			path: e.url,
			size: 20330
		});
		if (result) {
			const {
				data
			} = result;
			uni.uploadFile({
				url: data.host,
				filePath: e.url,
				name: 'file',
				formData: {
					key: data.key,
					policy: data.policy,
					OSSAccessKeyId: data.ossAccessKeyId,
					signature: data.signature
				},
				success: async (res) => {
					if (res.statusCode === 204) {
						const tailorImg = JSON.parse(res.data).data.filePath;
						isShowCrop.value = false;
						emits('uploadSuccess', tailorImg);
						emits('update:value', tailorImg);
						close();
					}
				}
			});
		}
	};
	// 权限检查
	const openModelRef = ref(null);
	const empowerCameraAlbum = (type) => {
		let bool = false;
		let yxPermission = uni.getStorageSync('yuexiang-permission');
		if (yxPermission && yxPermission.camera == 1) {
			bool = true;
		} else {
			openModelRef.value.openDialog({
				title: '提示',
				cancelText: '关闭',
				confirmText: '同意',
				content: `当前无法进行拍照或选择图片,是否授权打开摄像头拍照以及读取、写入相册权限?`,
				confirm: async () => {
					openModelRef.value.openTips(
						`当前未授权相册写入、读取和摄像头权限,无法上传图片,请同意授权摄像头、访问相册等权限,是否要打开设置授权定位相关权限?`
					);
					let res = await permision.requestAndroidPermission([
						'android.permission.CAMERA',
						'android.permission.WRITE_EXTERNAL_STORAGE',
						'android.permission.READ_EXTERNAL_STORAGE'
					]);
					if (res == 1) {
						bool = true;
					} else {
						openModelRef.value.openDialog({
							title: '提示',
							cancelText: '取消',
							confirmText: '去开启',
							content: `未授权相册写入、读取和摄像头权限,是否重新授权?`,
							confirm: () => permision.gotoAppPermissionSetting()
						});
						bool = false;
					}
					uni.setStorageSync('yuexiang-permission', {
						...yxPermission,
						camera: res
					});
					openModelRef.value.tipsPopup.close();
				}
			});
		}
		return bool;
	};
	const onDelItem = (index) => {
		images.value.splice(index, 1);
		emits('uploadSuccess', typeof images.value == 'string' ? images.value : images.value.join(','));
		emits('update:value', typeof images.value == 'string' ? images.value : images.value.join(','));
	};
	// 方法暴露
	defineExpose({
		uploadImg,
		empowerCameraAlbum,
		showPopup
	});
</script>

<style lang="scss">
	.custom_upload {
		width: 100%;

		.upload_content {
			padding: 25rpx;
			margin-bottom: 100rpx;
		}

		.choose_box {
			width: 100%;
			display: grid;
			grid-template-columns: 1fr 1fr 1fr;
			grid-row-gap: 20rpx;
			grid-column-gap: 30rpx;

			.images_box,
			.upload_box {
				width: 100%;
				height: 200rpx;
				border-radius: 17rpx;
			}

			.images_box {
				position: relative;
				animation: zoom 0.5s;
			}

			.close_icon {
				position: absolute;
				top: -15rpx;
				right: -10rpx;
				width: 35rpx;
				height: 35rpx;
				background: rgba(0, 0, 0, 0.5);
				border-radius: 50%;
			}

			.upload_box {
				background: #F4F5F9;
			}
		}
	}
</style>